﻿using CodeGenerator.Core;
using CodeGenerator.TemplateFactory;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CodeGenerator
{
    public partial class frmMain : Form
    {
        BindingList<CodeGenerator.Core.Table> databaseTables;
        CheckBox HeaderCheckBox;

        public frmMain()
        {
            InitializeComponent();
            databaseTables = new BindingList<Core.Table>();
            AddHeaderCheckBox();
        }

        private void btnGenerateConnectionStirng_Click(object sender, EventArgs e)
        {
            frmSqlConnectionWizard frmConnectionWizard = new frmSqlConnectionWizard();
            frmConnectionWizard.OnConnectionStringBuilt += frmConnectionWizard_OnConnectionStringBuilt;
            frmConnectionWizard.ShowDialog();
        }

        void frmConnectionWizard_OnConnectionStringBuilt(string connectionString)
        {
            txtConnectionString.Text = connectionString;
            GetTables(connectionString);
        }

        public void GetTables(string connectionString)
        {
            gridViewTables.AutoGenerateColumns = true;
           
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();
                DataTable schema = connection.GetSchema("Tables");
                foreach (DataRow row in schema.Rows)
                {
                    CodeGenerator.Core.Table table = new Core.Table();
                    table.TableName = row[2].ToString();
                    databaseTables.Add(table);
                }
            }
            List<Table> sortedTableList = databaseTables.OrderBy(o => o.TableName).ToList();
            BindingList<CodeGenerator.Core.Table> SortedList = new BindingList<Table>(sortedTableList);
            gridViewTables.DataSource = SortedList;
        }

        private void btnSearchLocation_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dlg = new FolderBrowserDialog())
            {
                dlg.Description = "Select the path to store the generated files";
                if (dlg.ShowDialog() != DialogResult.OK)
                    return;
                txtProjectPath.Text = dlg.SelectedPath;
                ProjectConfiguration.ProjectPath = dlg.SelectedPath;
            }
        }

        private void AddHeaderCheckBox()
        {
            HeaderCheckBox = new CheckBox();
            HeaderCheckBox.Size = new Size(15, 15);
            HeaderCheckBox.Click += HeaderCheckBox_Click;
            HeaderCheckBox.Location = new Point(20, 5);
            this.gridViewTables.Controls.Add(HeaderCheckBox);
        }

        void HeaderCheckBox_Click(object sender, EventArgs e)
        {
            foreach (Core.Table table in databaseTables)
                table.Selected = HeaderCheckBox.Checked;
            gridViewTables.Refresh();
        }

        private void gridViewTables_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (e.ColumnIndex == 0)
                {
                    bool isChecked = (Boolean)gridViewTables[0, e.RowIndex].FormattedValue;
                    if (isChecked)
                    {
                        foreach (Core.Table table in databaseTables)
                        {
                            if (table == (Core.Table)gridViewTables.Rows[e.RowIndex].DataBoundItem)
                            {
                                table.Selected = isChecked;
                                break;
                            }
                        }
                    }
                }
            }
            catch
            {
                
            }
            
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            if (txtApplicationName.Text.Trim() != string.Empty)
            {
                ProjectConfiguration.ProjectName = txtApplicationName.Text.Trim();

                SqlConnectionTemplate sqlConnectionTemplate = new SqlConnectionTemplate();
                if (!System.IO.Directory.Exists(String.Format("{0}\\DataLayer", txtProjectPath.Text)))
                    System.IO.Directory.CreateDirectory(String.Format("{0}\\DataLayer", txtProjectPath.Text));
                System.IO.File.WriteAllText(String.Format("{0}\\DataLayer\\ConnectionString.cs", txtProjectPath.Text), sqlConnectionTemplate.TransformText());

                SqlMapperTemplate sqlMapperTemplate = new SqlMapperTemplate();
                if (!System.IO.Directory.Exists(String.Format("{0}\\DataLayer", txtProjectPath.Text)))
                    System.IO.Directory.CreateDirectory(String.Format("{0}\\DataLayer", txtProjectPath.Text));
                System.IO.File.WriteAllText(String.Format("{0}\\DataLayer\\SqlMapper.cs", txtProjectPath.Text), sqlMapperTemplate.TransformText());

                progressBar.Maximum = databaseTables.Count;
                progressBar.Minimum = 0;
                this.Enabled = false;
                foreach (Core.Table table in databaseTables)
                {
                    panelPopUp.Visible = true;
                    if (table.Selected)
                    {
                        CRUDStoredProceduresTemplate proceduresTemplate = new CRUDStoredProceduresTemplate();
                        CRUDProcedureGenerator.ConnectionString = txtConnectionString.Text;
                        CRUDProcedureGenerator.TableToGenerate = table.TableName;
                        CRUDProcedureGenerator.DatabaseName = ProjectConfiguration.DatabaseName;
                        if (!System.IO.Directory.Exists(String.Format("{0}\\CRUDProcedures", txtProjectPath.Text)))
                            System.IO.Directory.CreateDirectory(String.Format("{0}\\CRUDProcedures", txtProjectPath.Text));
                        System.IO.File.WriteAllText(String.Format("{0}\\CRUDProcedures\\{1}.sql", txtProjectPath.Text, table.TableName), proceduresTemplate.TransformText());

                        EntityTemplate entityTemplate = new EntityTemplate();
                        EntityGenerator.TableToGenerate = table.TableName;
                        EntityGenerator.ConnectionString = txtConnectionString.Text;
                        EntityGenerator.DatabaseName = ProjectConfiguration.DatabaseName;
                        if (!System.IO.Directory.Exists(String.Format("{0}\\Entities", txtProjectPath.Text)))
                            System.IO.Directory.CreateDirectory(String.Format("{0}\\Entities", txtProjectPath.Text));
                        System.IO.File.WriteAllText(String.Format("{0}\\Entities\\{1}.cs", txtProjectPath.Text, table.TableName), entityTemplate.TransformText());

                        DataLayerFactoryTemplate dataLayerFactoryTemplate = new DataLayerFactoryTemplate();
                        DataLayerFactoryGenerator.TableToGenerate = table.TableName;
                        DataLayerFactoryGenerator.DatabaseName = ProjectConfiguration.DatabaseName;
                        DataLayerFactoryGenerator.ConnectionString = txtConnectionString.Text;
                        if (!System.IO.Directory.Exists(String.Format("{0}\\DataLayer", txtProjectPath.Text)))
                            System.IO.Directory.CreateDirectory(String.Format("{0}\\DataLayer", txtProjectPath.Text));
                        System.IO.File.WriteAllText(String.Format("{0}\\DataLayer\\{1}Repository.cs", txtProjectPath.Text, table.TableName), dataLayerFactoryTemplate.TransformText());

                        BusinessLayerTemplate businessLayerTemplate = new BusinessLayerTemplate();
                        BusinessLayerGenerator.TableToGenerate = table.TableName;
                        if (!System.IO.Directory.Exists(String.Format("{0}\\Business", txtProjectPath.Text)))
                            System.IO.Directory.CreateDirectory(String.Format("{0}\\Business", txtProjectPath.Text));
                        System.IO.File.WriteAllText(String.Format("{0}\\Business\\{1}Manager.cs", txtProjectPath.Text, table.TableName), businessLayerTemplate.TransformText());
                    }
                    progressBar.Increment(1);
                }
                panelPopUp.Visible = false;
                this.Enabled = true;
                MessageBox.Show("The code generation has finished successfully");
            }
            else
            {
                MessageBox.Show("Application name is required");
            }
        }

        private void txtApplicationName_TextChanged(object sender, EventArgs e)
        {
            ProjectConfiguration.ProjectName = txtApplicationName.Text.Trim();
            if(!String.IsNullOrEmpty(ProjectConfiguration.ProjectName.Trim()))
            {
                btnGenerate.Enabled = true;
                btnGenerateConnectionStirng.Enabled = true;
                btnSearchLocation.Enabled = true;
            }
            else
            {
                btnGenerate.Enabled = false;
                btnGenerateConnectionStirng.Enabled = false;
                btnSearchLocation.Enabled = false;
            }
        }
    }
}
